define(function () {
    var FSM = {};

    FSM.LinearFSM = function (params) {
        // params:
        //   len:
        //     number of states in FSM
        //   transition_handler:
        //     Function object specifying what to do during transition from i-sate to j-state.
        //     Must return dojo.Deferred object.
        //         function (from, to):
        //             from, to -- current and target state
        //
        this.params = params;
        // states: 0, 1, 2, ..., params.len-1 
        this.min_state = 0;
        this.max_state = params.len - 1;
        // initial state
        this.state = 0;
    };

    FSM.LinearFSM.prototype = {
        fwrd: function () {
            // forward event handler
            var state = this.state;
            // if we are in transition now than ignore event
            if (this._transition_lock) {
            	return;
            }
            // if we are in the end state than ignore event
            if (this.state === this.max_state) {
            	return;
            }
            // do transition from j to j+1
            this._do_transition(state, state + 1);
        },
        bwrd: function () {
            // backward event handler
            var state = this.state;
            // if we are in transition now than ignore event
            if (this._transition_lock) return;
            // if we are in the beginning state than ignore event
            if (this.state == this.min_state) return;
            
            // do transition from j to j-1
            this._do_transition(state, state - 1);
        },
        _do_transition: function (from, to) {
            var that = this;
            this._transition_lock = true;
            this.params.transition_handler(from, to).then(function () {
                that.state = to;
                that._transition_lock = false;
            });
        }
    };

    return FSM;
});




